﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace TurtlePoker
{
    class CardManager
    {
        protected Stack<Card> m_card_pile;
        protected List<Card> m_card_rep;

        public int card_number
        {
            get { return this.m_card_pile.Count; }
        }
        // ctor
        public CardManager()
        {
            m_card_pile = new Stack<Card>();
            m_card_rep = new List<Card> ();

            List<int> indice = new List<int> ();
            for (int i = 0; i < 54; i++)
            {
                indice.Add(i);
            }
            // shuffle algorithm
            // 1. randomly selected index i from indice[...]
            // 2. add Card[i] to card pile
            // 3. remove i from indice[...]
            // 4. return to step 1 until all the cards are added
            Random r = new Random();
            for (int i = 54; i > 0; i--)
            {
                int index = r.Next(i);
                int code = indice[index];
                Card c = new Card(code);
                indice.RemoveAt(index);
                m_card_pile.Push(c);
            }
        }

        // deal one card
        public Card deal()
        {
            Debug.Assert(m_card_pile.Count > 0);
            Card c = m_card_pile.Pop();
            return c;
        }

        // put one card into m_card_rep
        public void put(Card c)
        {
            Debug.Assert(m_card_rep.Count < Game.CARD_REP_LIMIT);
            m_card_rep.Add(c);
        }

        // replace one of the replaceable cards 
        public void replace_one(Card card_in, Card card_out)
        {
            Debug.Assert(this.m_card_rep.Count > 0);

            bool found = false;
            foreach (Card c in this.m_card_rep)
            {
                if (c == card_out)
                {
                    found = true;
                    break;
                }
            }
            Debug.Assert(found);

            this.m_card_rep.Remove(card_out);
            this.m_card_rep.Add(card_in);
        }

        // replace all the replaceable cards 
        public void replace(List<Card> cards_in)
        {
            Debug.Assert(cards_in.Count <= Game.CARD_REP_LIMIT);
            Debug.Assert(cards_in.Count > 0);
            Debug.Assert(cards_in.Count == m_card_rep.Count);

            this.m_card_rep.Clear();
            foreach (Card c in cards_in)
            {
                this.m_card_rep.Add(c);
            }
        }

        public bool empty()
        {
            return this.card_number == 0;
        }
        
        public void set_card_rep(List<Card> cards)
        {
            this.m_card_rep = cards;
        }

        public List<Card> get_card_rep()
        {
            return this.m_card_rep;
        }
    }
}
